//
//  TagReader.m
//  TagLib-ObjC
//
//  Created by Me on 01/07/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "TagReader.h"

#include <fileref.h>
#include "mpegfile.h"
#include "id3v2tag.h"
#include "id3v2frame.h"
#include "id3v2header.h"
#include "attachedpictureframe.h"
#include "unsynchronizedlyricsframe.h"  //处理mp3歌词
#include "mp4file.h" //aac,m4a
#include "mp4coverart.h"
#include "mp4tag.h"

#import "HCoreConfig.h"

using namespace TagLib;

static inline NSString *NSStr(TagLib::String _string)
{
    if (_string.isNull() == false) {
        return [NSString stringWithUTF8String:_string.toCString(true)];
    } else {
        return nil;
    }
}
static inline TagLib::String TLStr(NSString *_string)
{
    return TagLib::String([_string UTF8String], TagLib::String::UTF8);
}

@interface TagReader ()
{
    FileRef _file;
}

@end

@implementation TagReader
@synthesize path=_path;

- (id)initWithFileAtPath:(NSString *)path
{
    if (self = [super init]) {
        [self loadFileAtPath:path];
    }
    return self;
}
- (id)init
{
    return [self initWithFileAtPath:nil];
}

- (void)loadFileAtPath:(NSString *)path
{
    _path = path;
    
    if (_path != nil) {
        _file = FileRef([path UTF8String]);
    } else {
        _file = FileRef();
    }
}

//是否有效
-(BOOL)fileIsValid{
    if (_file.isNull()) {
        return NO;
    }

    return YES;
}


- (BOOL)save
{
    return (BOOL)_file.save();
}
- (BOOL)doubleSave
{
    return [self save] && [self save];
}

- (NSString *)title
{
    if (_file.tag())
    {
        return NSStr(_file.tag()->title());
    }
    else{
        return @"";
    }
    
}
- (void)setTitle:(NSString *)title
{
    title=CHECKSTR(title);
    
    _file.tag()->setTitle(TLStr(title));
}
- (NSString *)artist
{
    if (_file.tag())
    {
        return NSStr(_file.tag()->artist());
    }
    
    return @"";
    
}
- (void)setArtist:(NSString *)artist
{
    artist=CHECKSTR(artist);
    _file.tag()->setArtist(TLStr(artist));
}
- (NSString *)album
{
    if (_file.tag())
    {
        return NSStr(_file.tag()->album());
    }
    
    return @"";
}
- (void)setAlbum:(NSString *)album
{
    album=CHECKSTR(album);
    _file.tag()->setAlbum(TLStr(album));
}
- (NSNumber *)year
{
    if (_file.tag())
    {
        return [NSNumber numberWithUnsignedInt:_file.tag()->year()];
    }
    
    return [NSNumber numberWithUnsignedInt:2000];
}
- (void)setYear:(NSNumber *)year
{
    _file.tag()->setYear([year unsignedIntValue]);
}
- (NSString *)comment
{
    if (_file.tag())
    {
        return NSStr(_file.tag()->comment());
    }
    
    return @"";
}
- (void)setComment:(NSString *)comment
{
    comment=CHECKSTR(comment);
    _file.tag()->setComment(TLStr(comment));
}
- (NSNumber *)track
{

    return [NSNumber numberWithUnsignedInt:_file.tag()->track()];
}
- (void)setTrack:(NSNumber *)track
{
    
    
    _file.tag()->setTrack([track unsignedIntValue]);
}
- (NSString *)genre
{
    return NSStr(_file.tag()->genre());
}
- (void)setGenre:(NSString *)genre
{
    genre=CHECKSTR(genre);
    
    _file.tag()->setGenre(TLStr(genre));
}
- (NSData *)albumArt
{
   
    MPEG::File *file = dynamic_cast<MPEG::File *>(_file.file());
    if (file != NULL) {

        ID3v2::Tag *tag = file->ID3v2Tag();
        if (tag) {
            ID3v2::FrameList frameList = tag->frameListMap()["APIC"];
            ID3v2::AttachedPictureFrame *picture = NULL;
            
            if (!frameList.isEmpty() && NULL != (picture = dynamic_cast<ID3v2::AttachedPictureFrame *>(frameList.front()))) {
                TagLib::ByteVector bv = picture->picture();
                return [NSData dataWithBytes:bv.data() length:bv.size()];
            }
        }
    }
    
    
    
    
    return nil;
}
- (void)setAlbumArt:(NSData *)albumArt
{


    
    
    MPEG::File *file = dynamic_cast<MPEG::File *>(_file.file());

    if (file != NULL) {

        NSString * ext=_path.pathExtension.lowercaseString;
        
        ID3v2::Tag *tag = file->ID3v2Tag();
        if (tag) {
            tag->removeFrames("APIC");
            if (albumArt != nil && [albumArt length] > 0) {
                ID3v2::AttachedPictureFrame *picture = new ID3v2::AttachedPictureFrame();
                
                TagLib::ByteVector bv = ByteVector((const char *)[albumArt bytes], [albumArt length]);
                picture->setPicture(bv);
                picture->setMimeType(String("image/jpg"));
                picture->setType(ID3v2::AttachedPictureFrame::FrontCover);
                
                tag->addFrame(picture);
            }
       
            
        }
    }
}




//歌词比较特殊,读取
-(NSString*)lyrics{

    
//参考： http://stackoverflow.com/questions/11051055/how-to-get-the-lyrics-of-a-song-from-the-song-file

    NSString * hlyrics=nil;
    
    if (_file.tag())
    {
        //mp3 版本
        NSString * ext=_path.pathExtension.lowercaseString;
        
    if ([ext isEqualToString:@"aac"] || [ext isEqualToString:@"m4a"] || [ext isEqualToString:@"m4"]) {
        
        
            TagLib::MP4::File f2([_path UTF8String]);
            TagLib::MP4::Item item = f2.tag()->itemListMap()["\xa9lyr"];
            TagLib::StringList strings = item.toStringList();
            if (!strings.isEmpty()) {
                // As above, there could be multiple strings.

                hlyrics=NSStr(strings.front());
            }
        
    } else
        //暂时其他都按mp3处理
        // if ([ext isEqualToString:@"mp3"]||[ext isEqualToString:@"mp2"] ) {
    {
        TagLib::MPEG::File f1([_path UTF8String]);
        TagLib::ID3v2::FrameList frames = f1.ID3v2Tag()->frameListMap()["USLT"];
        if (!frames.isEmpty()) {
            ID3v2::UnsynchronizedLyricsFrame *frame =
            dynamic_cast<TagLib::ID3v2::UnsynchronizedLyricsFrame *>(frames.front());
            // There could be multiple frames here; you may want to look at language
            // and/or description, instead of just picking the first.
            hlyrics=NSStr(frame->text());
        }
    }
  
        
    }
    
    return CHECKSTR(hlyrics) ;

}


#pragma --mark 针对mp4的音频文件处理
//http://www.devdiv.com/home.php?mod=space&uid=40553&do=blog&quickforward=1&id=49544

+(void)writeArtworkForAAcWithPath:(NSString*)thePath imageData:(NSData*)imgdata{


    if (![thePath isEqualToString:@""]) {
        
        
        // read the image file
        TagLib::ByteVector bv = ByteVector((const char *)[imgdata bytes],  (unsigned int)[imgdata length]);
        
        // read the image file
        TagLib::MP4::CoverArt coverArt((TagLib::MP4::CoverArt::Format) 0x0D,   bv);
        
        // read the mp4 file
        TagLib::MP4::File audioFile([thePath UTF8String]);
        
        if(!audioFile.isValid()){
            return;
        }

        
        

        // get the tag ptr
        TagLib::MP4::Tag *tag = audioFile.tag();
        
        if (tag->isEmpty()) {
            return;
        }

            // get the items map
            TagLib::MP4::ItemListMap itemsListMap = tag->itemListMap();
            
            // create cover art list
            TagLib::MP4::CoverArtList coverArtList;
            
            // append instance
            coverArtList.append(coverArt);
            
            // convert to item
            TagLib::MP4::Item coverItem(coverArtList);
            
            // add item to map
            itemsListMap.insert("covr", coverItem);
            
            tag->itemListMap() = itemsListMap;//需要重新赋值
            
            tag->save();
            //audioFile.save();
  
        
    }
    


}


- (void)dealloc
{
    _path = nil;
}

@end
